package org.bambrikii.examples.rutext.lexer.custom;

import org.bambrikii.examples.rutext.lexer.ILexer;
import org.bambrikii.examples.rutext.lexer.impl.FractionDelimiterLexer;
import org.bambrikii.examples.rutext.lexer.impl.FractionPowLexer;
import org.bambrikii.examples.rutext.lexer.impl.LexerBase;
import org.bambrikii.examples.rutext.parser.IParser;
import org.bambrikii.examples.rutext.parser.ParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FractionPartLexer extends LexerBase<Double> {

	private static final Logger logger = LoggerFactory.getLogger(FractionPartLexer.class);

	public FractionPartLexer(IParser parser) {
		super(parser);
		addChild(new FractionDelimiterLexer(getParser()));
		addChild(new IntegerLexer(getParser()));
		addChild(new FractionPowLexer(getParser()));
	}

	@Override
	public Double lex() throws ParserException {
		Double result = new Double(0);
		Long previousValue = null;
		Double additiveValue = new Double(0);
		int n = 0;
		while (hasNext()) {
			logger.debug("[" + getLast() + "]");
			int childenProcessed = 0;
			for (ILexer<?> child : getChildren()) {
				Object obj = child.lex();
				// logger.debug("[" + getLast() + "]");
				if (obj != null) {
					n++;
					if (child instanceof IntegerLexer) {
						Long currentValue = (Long) obj;
						if (previousValue == null || currentValue < previousValue) {
							additiveValue = additiveValue + currentValue.doubleValue();
							previousValue = currentValue;
						}
						logger.debug("result:" + result + ", additiveValue: " + additiveValue + ", previousValue: "
								+ previousValue);
						break;
					} else if (child instanceof FractionDelimiterLexer) {
						Short result2 = (Short) obj;
						if (result2 != null) {
							result = new Double(0);
							previousValue = null;
							additiveValue = new Double(0);
							logger.debug("result:" + result + ", additiveValue: " + additiveValue + ", previousValue: "
									+ previousValue + ", result2:" + result2);
						}
						logger.debug("result:" + result + ", additiveValue: " + additiveValue + ", previousValue: "
								+ previousValue);
						break;
					} else if (child instanceof FractionPowLexer) {
						Double currentValue = (Double) obj;
						previousValue = null;
						result = addDecimal(result, additiveValue, currentValue);
						logger.debug("result:" + result + ", additiveValue: " + additiveValue + ", previousValue: "
								+ previousValue);
						additiveValue = new Double(0);
						break;
					}
				}
				childenProcessed++;
			}
			if (getChildren().size() == childenProcessed) {
				logger.debug("skipping [" + getLast() + "]");
				break;
			}
		}
		if (n > 0) {
			return result;
		}
		return null;
	}

	private Double addDecimal(Double result, Double additiveValue, Double currentValue) {
		result = result + additiveValue * currentValue;
		return result;
	}
}
